<template>
    <div class="menu-config-box">
        <el-button type="primary"
                   @click="onClickAdd"
                   size="mini">新增</el-button>
        <el-tree :data="data"
                 draggable
                 default-expand-all
                 :expand-on-click-node="false"
                 node-key="id"
                 ref="tree"
                 :props="defaultProps"
                 @check="checkTree"
                 @node-drop="nodeDropEed">
            <span class="custom-tree-node"
                  slot-scope="{ node, data }">
                <span>
                    <i :class="data.icon"></i>
                    {{ node.label }}
                </span>
                <span class="custom-tree-node-btns">
                    <el-button type="text"
                               size="mini"
                               @click="() => handleEditor(node, data)">编辑</el-button>
                    <el-button type="text"
                               size="mini"
                               @click="() => handleAppend(node, data)">新增</el-button>
                    <el-button type="text"
                               size="mini"
                               @click="() => handleRemove(node, data)">删除</el-button>
                </span>
            </span>
        </el-tree>
        <el-dialog title="路由编辑"
                   width="50%"
                   :visible.sync="dialogVisible"
                   class="custom-dialog"
                   append-to-body
                   :close-on-click-modal="false">
            <SoftwareMenuEditor v-if="software"
                                :currentCheckedNode="currentCheckedNode"
                                @on-save="onSaveEditor" />
            <MenuItemEditor v-else
                            :allPaths="allPaths"
                            :currentCheckedNode="currentCheckedNode"
                            @on-save="onSaveEditor" />
        </el-dialog>
    </div>
</template>
<script>
import MenuItemEditor from "./menu-item-editor";
import SoftwareMenuEditor from "./software-menu-editor";

export default {
    name: "CustomMenuView",
    components: {
        MenuItemEditor,
        SoftwareMenuEditor,
    },
    props: {
        treeData: {
            type: Array,
            default: function () {
                return [];
            },
        },
        software: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
            dialogVisible: false,
            allPaths: [],
            currentCheckedNode: {},
            currentNode: {},
            data: this.treeData, //MenuConfig,
            defaultProps: {
                children: "children",
                label: "label",
            },
            checkedTreeData: [],
        };
    },
    watch: {
        treeData: {
            handler: function (tree) {
                let allPaths = [];
                let loop = function (data) {
                    data.filter((item) => {
                        allPaths.push({
                            title: item.name,
                            path: item.path,
                            key: item.path,
                        });
                        if (item.children) {
                            loop(item.children);
                        }
                    });
                };
                loop(tree);
                this.allPaths = allPaths;
            },
            immediate: true,
        },
    },
    methods: {
        checkTree(currentNode, checked) {
            const data = JSON.parse(JSON.stringify(this.$refs.tree.data));
            const checkKeys = checked.checkedKeys.concat(
                checked.halfCheckedKeys
            );
            let loopFilter = function (data, keys) {
                return data.filter((item) => {
                    if (keys.indexOf(item.id) > -1) {
                        if (item.children) {
                            item.children = loopFilter(item.children, keys);
                        }
                        return item;
                    }
                });
            };
            this.checkedTreeData = loopFilter(data, checkKeys);
        },
        onClickAdd() {
            const node = this.$refs.tree.root;
            const data = {
                label: "",
                name: "",
                path: "",
                icon: "el-icon-s-tools",
            };
            this.handleAppend(node, data);
        },
        handleEditor(node, data) {
            this.dialogVisible = true;
            this.currentCheckedNode = JSON.parse(JSON.stringify(data));
            this.currentNode = node;
        },
        handleAppend(node, data) {
            const newChild = {
                label: "",
                name: "",
                path: "",
                icon: "el-icon-s-tools",
                children: [],
            };
            if (!data.children) {
                this.$set(data, "children", []);
            }
            this.dialogVisible = true;
            this.currentCheckedNode = newChild;
            this.currentNode = node;
        },
        handleRemove(node, data) {
            const parent = node.parent;
            const children = parent.data.children || parent.data;
            const index = children.findIndex((d) => d.id === data.id);
            children.splice(index, 1);
            this.$emit("on-save", this.data);
        },
        onSaveEditor(data) {
            const node = this.currentNode;
            const parent = node.parent;
            if (data.id) {
                //编辑
                const children = parent.data.children || parent.data;
                const index = children.findIndex((d) => d.id === data.id);
                children.splice(index, 1, data);
            } else {
                //新增
                const id = Number(
                    Math.random().toString().substr(3, 32) + Date.now()
                ).toString(36);
                let current = JSON.parse(JSON.stringify(data));
                current.id = id;
                if (parent) {
                    this.currentNode.data.children.push(current);
                } else {
                    this.currentNode.data.push(current);
                }
            }
            this.dialogVisible = false;
            this.$emit("on-save", this.data);
        },
        nodeDropEed() {
            this.$emit("on-save", this.data);
        },
    },
    created() {
        this.$emit("on-save", this.data);
    },
};
</script>
<style lang="scss" scoped>
.menu-config-box {
    line-height: 32px;
    .custom-tree-node {
        width: 100%;
        &-btns {
            float: right;
            padding-right: 10px;
            &::before {
                content: "";
                display: block;
                clear: both;
            }
        }
    }
}
</style>
